package com.tengju.bff.interfaces.login.facade;

import com.tengju.bff.interfaces.login.assembler.UserAccountAssembler;
import com.tengju.bff.interfaces.shared.InterfaceCode;
import com.tengju.bff.interfaces.shared.InterfaceException;
import com.tengju.bff.interfaces.shared.servlet.ServletContextUtil;
import com.tengju.bff.interfaces.shared.servlet.UserServletContext;
import com.tengju.support.application.message.PushCidBindService;
import com.tengju.support.domain.model.user.UserId;
import com.tengju.user.application.login.UserAccountService;
import com.tengju.user.application.login.dto.*;
import com.tengju.user.application.login.vo.LoginVO;
import com.tengju.user.domain.model.login.*;
import com.tengju.user.domain.model.user.UserAccountRepository;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.shared.AESUtil;
import com.tengju.user.domain.shared.Constant;
import com.tengju.user.domain.shared.IdObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author wuziyang
 */
@Service
public class UserAccountFacade {

    @Autowired
    UserAccountRepository userAccountRepository;

    @Autowired
    UserInfoRepository userInfoRepository;

    @Autowired
    UserAccountService userAccountService;

    @Autowired
    PushCidBindService pushCidBindService;

    public LoginVO login(LoginDTO loginDTO) throws Exception {

        UserServletContext servletContext = ServletContextUtil.getServletContext();

        LoginForm loginForm = new LoginForm(loginDTO.getAreaCode(),
                loginDTO.getUsername(),
                loginDTO.getPassword(),
                loginDTO.getVerificationCode(),
                UserType.fromVal(loginDTO.getUserType()),
                LoginType.fromVal(loginDTO.getLoginType()),
                servletContext.getIp(),
                LocalDateTime.now(),
                servletContext.getFrom());

        UserAccount userAccount = userAccountRepository
                .queryUserAccount(loginForm.username(),
                        loginForm.getUserType());

        LoginResult loginResult = userAccountService.login(loginForm, userAccount);

        String mobile = null;
        if (loginDTO.getUserType().equals(UserType.USER.getVal())) {
            mobile = loginDTO.getUsername();
        }

        return new LoginVO(AESUtil.encrypt(Constant.USERID_ENCRYPT_KEY, loginResult.getUserId() + ""),
                loginResult.getUsername(),
                loginResult.getNickName(),
                loginResult.getHeadImage(),
                loginResult.getToken(),
                mobile,
                null);
    }

    public boolean logout(LogoutDTO logoutDTO) throws Exception {

        HttpServletRequest request = ServletContextUtil.getRequest();
        if (request == null) {
            throw new InterfaceException(InterfaceCode.SYSTEM_ERROR);
        }
        String token = request.getHeader("tj_token");

        LogoutInfo logoutInfo = UserAccountAssembler.dtoToModel(logoutDTO, token);

        UserServletContext servletContext = ServletContextUtil.getServletContext();

        IdObject id = null;
        if (servletContext.getUserType() == UserType.USER) {
            id = servletContext.getUserId();
        } else if (servletContext.getUserType() == UserType.STAFF) {
            id = servletContext.getStaffId();
        }

        if (id == null) {
            throw new InterfaceException(InterfaceCode.BUSINESS_FAIL);
        }

        //推送cid解绑
        pushCidBindService.unbind(new UserId(id.getValue()));


        return userAccountService.logout(logoutInfo, id, servletContext.getUserType());
    }


    public LoginVO pwdChange(PwdChangeDTO pwdChangeDTO) throws Exception {

        UserAccount userAccount = userAccountService.pwdChange(pwdChangeDTO);

        //密码变更成功 执行登录
        if (userAccount != null) {
            LoginForm loginInfo = new LoginForm(pwdChangeDTO.getAreaCode(),
                    pwdChangeDTO.getMobile(), pwdChangeDTO.getNewPassword(),
                    null, UserType.USER, LoginType.PWD_LOGIN,
                    ServletContextUtil.getServletContext().getIp(), LocalDateTime.now(),
                    ServletContextUtil.getServletContext().getFrom());
            LoginResult loginResult = userAccountService.login(loginInfo, userAccount);
            return new LoginVO(AESUtil.encrypt(Constant.USERID_ENCRYPT_KEY, loginResult.getUserId() + ""),
                    loginResult.getUsername(),
                    loginResult.getNickName(),
                    loginResult.getHeadImage(),
                    loginResult.getToken(),
                    pwdChangeDTO.getMobile(),
                    null);
        } else {
            throw new InterfaceException(InterfaceCode.PWD_CHANGE_FAIL);
        }

    }

    public void addManageUser(RegisterDTO registerDTO) {
        userAccountService.addManageUser(registerDTO);
    }

    public LoginVO weChatLogin(WeChatLoginDTO weChatLoginDTO) {
        UserServletContext servletContext = ServletContextUtil.getServletContext();
        LoginForm loginForm = new LoginForm(
                UserType.USER,
                LoginType.QY_WECHAT_MINI_PROGRAM_LOGIN,
                servletContext.getIp(),
                LocalDateTime.now(),
                servletContext.getFrom(),
                weChatLoginDTO.getAuthCode()
        );

        // 微信登录场景无法获取用户信息
        UserAccount userAccount = new UserAccount(null, null, null, null
                , null, null, null, null, null);

        LoginResult loginResult = userAccountService.login(loginForm, userAccount);
        return new LoginVO(AESUtil.encrypt(Constant.USERID_ENCRYPT_KEY, loginResult.getUserId() + ""),
                loginResult.getUsername(),
                loginResult.getNickName(),
                loginResult.getHeadImage(),
                loginResult.getToken(),
                loginResult.getUsername(),
                loginResult.getUserIdCode().getValue());
    }
}
